
package proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.e885.log.E885Logger;

/**
 * 動態代理物件<br>
 * <br>
 * HelloSpeaker 本身的職責是顯示文字(System.out.println), 卻必須插入記錄(Log)動作, 這使得 HelloSpeaker 的職責加重, 在 AOP 的術語來說,<br>
 * 記錄的程式碼 cross-cutting 到 HelloSpeaker 的程式執行流程中, 記錄這樣的動作在 AOP 稱之為 cross-cutting concern.<br>
 * <br>
 * 使用代理物件將記錄與商務邏輯無關的動作或任務提取出來, 設計為一個服務物件, 如同靜態代理的 HelloProxy class 或和動態代理 HelloProxy class(這個 class),<br>
 * 這樣的物件在 AOP 稱之為 Aspect.<br>
 * <br>
 * AOP 中的 Aspect 所指的可以像是記錄等這類的動作或服務, 您將這些動作(cross-cutting concerns)設計為通用或不介入特定邏輯的一個職責清楚的 Aspect 物件,<br>
 * 這就是所謂的 Aspect-oriented programming, AOP<br>
 * <br>
 * 在好的設計之下, Aspect 可以獨立於應用程式之外, 在必要的時候, 可以介入應用程式之中提供服務, 而不需要相關服務的時候, 又可以將這些 Aspect 直接從應用程式中脫離, <br>
 * 而應用程式本身不須修改任何一行程式碼<br>
 * 
 * @author Eric.Kao(gau168.gau@msa.hinet.net)
 * @version 1.0
 * @company E885 Group
 * @copyright Copyright (c) 2001-2008
 */

public class HelloProxy implements InvocationHandler
{
	// 被代理的物件
	private Object delegate;

	/**
	 * 建立一個代理的物件
	 * 
	 * @param delegate 被代理的物件
	 * @return 代理物件
	 */
	public Object bind( Object delegate )
	{
		this.delegate = delegate;

		// 建立一個代理物件, 建立代理物件時必須告知所要被代理的介面
		return Proxy.newProxyInstance( delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
	 */
	public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
	{
		Object result = null;
		try
		{
			E885Logger.testLog.debug( "在方法執行之前，記錄 log" );

			result = method.invoke( delegate, args );

			E885Logger.testLog.debug( "在方法執行之後，記錄 log" );

			return result;
		}
		catch( Exception e )
		{
			e.printStackTrace();
			return null;
		}
	}

}
